﻿using Nop.Core;
using Nop.Core.Domain.Directory;
using Nop.Core.Infrastructure;
using Nop.Services.Directory;
using Nop.Services.Logistics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SpotsHub.Gateway.Utilities
{
    public static class AddressHelper
    {
        #region Fields

        private static int? countryId = null;
        private static int? provinceId = null;
        private static string countryName = null;
        private static string provinceName = null;

        #endregion

        public static int GetDefaultCountryId()
        {
            if (!countryId.HasValue)
            {
                GetDefaultCountry();

            }

            return countryId.Value;
        }

        public static string GetDefaultCountryName()
        {
            if (countryName == null)
            {
                GetDefaultCountry();
            }

            return countryName;
        }

        public static Country GetDefaultCountry()
        {
            try
            {
                var countryService = EngineContext.Current.Resolve<ICountryService>();
                var c = countryService.GetAllCountries().Single();
                countryId = c.Id;
                countryName = c.Name;
                return c;
            }
            catch (Exception e)
            {
                throw new NopException("Cannot get default country ID.", e);
            }
        }

        public static int GetDefaultProvinceId()
        {
            if (!provinceId.HasValue)
            {
                GetDefaultProvince();
            }

            return provinceId.Value;
        }

        public static string GetDefaultProvinceName()
        {
            if (provinceName == null)
            {
                GetDefaultProvince();
            }

            return provinceName;
        }

        public static StateProvince GetDefaultProvince()
        {
            const string defaultProvName = "British Columbia";
            try
            {
                var provinceService = EngineContext.Current.Resolve<IStateProvinceService>();
                var province = provinceService.GetStateProvincesByCountryId(GetDefaultCountryId())
                    .Single(p => p.Name.Equals(defaultProvName, StringComparison.InvariantCultureIgnoreCase));

                provinceId = province.Id;
                provinceName = province.Name;
                return province;
            }
            catch (Exception e)
            {
                throw new NopException("Cannot get province ID of " + defaultProvName, e);
            }
        }

        public static StateProvince GetProvinceByRegion(Region region)
        {
            if (region == null)
            {
                return GetDefaultProvince();
            }

            var district = region.Districts.FirstOrDefault();
            if (district == null)
            {
                return GetDefaultProvince();
            }
            else
            {
                return district.StateProvince;
            }
        }

        public static Region GetRegionByProvinceId(int? provinceId)
        {
            if (!provinceId.HasValue)
            {
                return null;
            }

            var logisiticsService = EngineContext.Current.Resolve<ILogisticsService>();
            var district = logisiticsService.GetAllDistricts().FirstOrDefault(x => x.StateProvinceId == provinceId);
            if (district == null)
            {
                return logisiticsService.GetAllRegions().FirstOrDefault();
            }
            else
            {
                return district.Region;
            }
        }

        public static Region GetRegionByPostalCode(string zipPostalCode)
        {
            if (String.IsNullOrEmpty(zipPostalCode))
            {
                return null;
            }

            var logisiticsService = EngineContext.Current.Resolve<ILogisticsService>();
            var district = logisiticsService.GetDistrictByZipPostalCode(zipPostalCode);
            if (district == null)
            {
                return logisiticsService.GetAllRegions().FirstOrDefault();
            }
            else
            {
                return district.Region;
            }
        }

        public static string GetTimeZoneIdByRegion(Region region)
        {
            if (region == null)
            {
                return "Pacific Standard Time";
            }

            var district = region.Districts.FirstOrDefault();
            if (district == null)
            {
                return "Pacific Standard Time";
            }
            return district.TimeZoneId;
        }
    }
}